<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>柱状图</title>
  <style>
    .cvs{border:solid 1px black;}
  </style>
</head>
<body>
  <canvas class="cvs"></canvas>
</body>
<script>
  const cvs = document.querySelector(".cvs")
  cvs.width = 480;
  cvs.height = 400;
  
  const c2d = cvs.getContext("2d");

  const data = [{
    "title": "星期一",
    "number": 100
  },{
    "title": "星期二",
    "number": 150
  },{
    "title": "星期三",
    "number": 700
  },{
    "title": "星期四",
    "number": 559
  },{
    "title": "星期五",
    "number": 180
  },{
    "title": "星期六",
    "number": 680
  }];

  const origin = {x:40, y:360};
  const axleMax = {x:440, y:40};

  // 绘制坐标轴
  drawAxle(origin, axleMax);
  // 绘制坐标轴的刻度
  drawAxleScale(data, origin, axleMax);
  // 绘制具体的数据柱
  drawColumn(data, origin, axleMax);

  function drawColumn(data, origin, axleMax){
    // 计算x轴两个刻度之间的间距
    const spacingX = (axleMax.x - origin.x - 40) / data.length;
    // 计算y轴两个刻度之间的间距
    const maxY = origin.y - axleMax.y - 40;
    const yMaxScale = Math.ceil(getMax(data, "number")/100);
    const spacingY = parseInt(maxY / yMaxScale);

    // 根据两个刻度之间的间距，计算柱的宽度
    const w = parseInt(spacingX * 0.5);

    data.forEach(val=>{
      const h = spacingY / 100 * val.number;
      const x = val.x - w/2;
      const y = origin.y - h;
      c2d.fillRect(x, y, w, h);
      c2d.textBaseline = "bottom";
      c2d.fillText(val.number, val.x, y);
    })
  }

  // 绘制坐标轴刻度功能
  function drawAxleScale(data, origin, axleMax){
    // x轴可绘制尺寸
    const maxX = axleMax.x - origin.x - 40;
    // 计算两个刻度之间的间距
    const spacingX = maxX / data.length;
    // 计算第一个x轴刻度的x
    const nowX = origin.x + 40;
    // 刻度
    for(let i=0;i<data.length;i++){
      c2d.moveTo(nowX + i*spacingX, origin.y);
      c2d.lineTo(nowX + i*spacingX, origin.y-10);
      c2d.stroke();

      // 记录当前数据的x轴的刻度坐标x
      data[i].x = nowX + i*spacingX;

      c2d.textAlign = "center";
      c2d.textBaseline = "middle";
      c2d.font = "12px 黑体";
      c2d.fillText(data[i].title, nowX+i*spacingX, origin.y+10);
    }

    // y轴可绘制尺寸
    const maxY = origin.y - axleMax.y - 40;

    // 取数据最大值计算y轴的刻度个数
    const yMaxScale = Math.ceil(getMax(data, "number")/100);
    // 计算两个刻度之间的间距
    const spacingY = parseInt(maxY / yMaxScale);
    // 刻度
    for(let i=0;i<yMaxScale;i++){
      c2d.moveTo(origin.x, origin.y - (i+1)*spacingY );
      c2d.lineTo(origin.x+10, origin.y - (i+1)*spacingY);
      c2d.stroke();

      c2d.textAlign = "center";
      c2d.textBaseline = "middle";
      c2d.font = "12px 黑体";
      c2d.fillText((i+1)*100, origin.x-20, origin.y - (i+1)*spacingY);
    }
  }

  // 取出数组内所有对象的指定属性的最大值
  function getMax(data, attr){
    return  Math.max(...data.map(val=>val.number));
  }

  // 绘制坐标轴功能
  function drawAxle(origin,axleMax){
    // x轴
    c2d.moveTo(origin.x, origin.y);
    c2d.lineTo(axleMax.x, origin.y);
    c2d.lineTo(axleMax.x, origin.y-4);
    c2d.lineTo(axleMax.x+4, origin.y);
    c2d.lineTo(axleMax.x, origin.y+4);
    c2d.lineTo(axleMax.x, origin.y);
    c2d.fill();
    
    // y轴
    c2d.moveTo(origin.x, origin.y);
    c2d.lineTo(origin.x, axleMax.y);
    c2d.lineTo(origin.x-4, axleMax.y);
    c2d.lineTo(origin.x, axleMax.y-4);
    c2d.lineTo(origin.x+4, axleMax.y);
    c2d.lineTo(origin.x, axleMax.y);
    c2d.fill();

    c2d.lineWidth = 2;
    c2d.stroke();
  }


  // 封装一个柱状图类
    // 参数：
      // 数据，必传
      // 标题
      // 是否显示x轴文字
      // 是否显示y轴文字
      // 是否显示每个柱的提示文字
      // 各个文字的颜色
      // 柱的颜色
      // ...



</script>
</html>